#include "RibbonPosnCtrlState.h"
#include "Animations.h"

RibbonPosnCtrlStateMachine_On g_RibbonPosnCtrlStateMachineOn;

void InitRibbonPosnCtrlStateMachineOn(void)
{
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineUnlock_.sm_.Entry = RibbonPosnEffectStateMachineUnlockEntry;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineUnlock_.sm_.Excute = RibbonPosnEffectStateMachineUnlockExcute;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineUnlock_.sm_.Exit = RibbonPosnEffectStateMachineUnlockExit;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineUnlock_.sm_.waitExitCount_ = 0;

    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineLock_.sm_.Entry = RibbonPosnEffectStateMachineLockEntry;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineLock_.sm_.Excute = RibbonPosnEffectStateMachineLockExcute;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineLock_.sm_.Exit = RibbonPosnEffectStateMachineLockExit;    
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineLock_.sm_.waitExitCount_ = 0;

    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineOff_.sm_.Entry = RibbonPosnEffectStateMachineOffEntry;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineOff_.sm_.Excute = RibbonPosnEffectStateMachineOffExcute;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineOff_.sm_.Exit = RibbonPosnEffectStateMachineOffExit;   
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineOff_.sm_.waitExitCount_ = 0;

    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineDefault_.sm_.Entry = RibbonPosnEffectStateMachineDefaultEntry;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineDefault_.sm_.Excute = RibbonPosnEffectStateMachineDefaultExcute;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineDefault_.sm_.Exit = RibbonPosnEffectStateMachineDefaultExit;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineDefault_.sm_.waitExitCount_ = 0;

    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineAll_.sm_.Entry = RibbonPosnEffectStateMachineAllEntry;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineAll_.sm_.Excute = RibbonPosnEffectStateMachineAllExcute;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineAll_.sm_.Exit = RibbonPosnEffectStateMachineAllExit;
    g_RibbonPosnCtrlStateMachineOn.ribbonPosnEffectStateMachineAll_.sm_.waitExitCount_ = 0;

    g_RibbonPosnCtrlStateMachineOn.sm_.Entry = RibbonPosnCtrlStateMachineOnEntry;
    g_RibbonPosnCtrlStateMachineOn.sm_.Excute = RibbonPosnCtrlStateMachineOnExcute;
    g_RibbonPosnCtrlStateMachineOn.sm_.Exit = RibbonPosnCtrlStateMachineOnExit;
    g_RibbonPosnCtrlStateMachineOn.sm_.waitExitCount_ = 0;
}

void RibbonPosnCtrlStateMachineOffEntry(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineOffEntry" << std::endl;
    resetLeFrntTurnLampRibbonUnlockAnimation();
    resetLeFrntTurnLampRibbonLockAnimation();
}

void RibbonPosnCtrlStateMachineOffExcute(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineOffExcute" << std::endl;
}

void RibbonPosnCtrlStateMachineOffExit(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineOffExit" << std::endl;
}

void RibbonPosnEffectStateMachineUnlockEntry(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineUnlockEntry" << std::endl;
    g_DayTimeAndPosLampView.model_->mask_ = 0x00;
    g_DayTimeAndPosLampView.model_->onOffStatus_ = OnOff_Off;
    g_DayTimeAndPosLampView.model_->pwm_ = 0.0;
    g_LeFrntTrunLampView.model_->mask = 0x00,
    g_LeFrntTrunLampView.model_->pwm_ = 0.0;
    g_LeFrntTrunLampView.model_->onOffStatus_ = OnOff_Off;
    g_StarrySkyView.model_->mask_ = 0x00,
    g_StarrySkyView.model_->onOffStatus_ = OnOff_Off;
    g_StarrySkyView.model_->pwm_ = 0.0;
}

void RibbonPosnEffectStateMachineUnlockExcute(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineUnlockExcute" << std::endl;
    switch(g_RibbonAnimationModel.posnMode_)
    {
        case Init:
        {
            if(isLeFrntTurnLampRibbonUnlockAnimationPlaying())
            {
                playLeFrntTurnLampRibbonUnlockAnimation();
            }
            else
            {
                //Ignore
            }
            g_RibbonView.model_->frntRibbonLampEffectShowSt_ = RibbonEffectShow_OFF;
            g_RibbonView.model_->frntRibbonLampEffectSt_     = RibbonEffectSel_Initial;
            break;
        }
        case Pause:
        {
            g_RibbonView.model_->frntRibbonLampEffectShowSt_ = RibbonEffectShow_Pause;
            break;
        }
        case Repeat:
        {
            playLeFrntTurnLampRibbonUnlockAnimation();
            repeatLeFrntTurnLampRibbonUnlockAnimation();
            break;
        }
        case Hold:
        {
            playLeFrntTurnLampRibbonUnlockAnimation();
            break;
        }
        case LeTurnLampOccupy:
        {
            if(g_RibbonAnimationModel.posnMode_ != g_RibbonAnimationModel.lastPosnMode_)
            {
                // std::cout << "LeTurnLampOccupy" << std::endl;
                justCloseRibbonLeFrntTurnLamp();
            }
            g_RibbonView.model_->frntRibbonLampEffectShowSt_ = RibbonEffectShow_Running;
            break;
        }
        default:
        {
            
            g_RibbonView.model_->frntRibbonLampEffectShowSt_ = RibbonEffectShow_OFF;
            g_RibbonView.model_->frntRibbonLampEffectSt_     = RibbonEffectSel_Initial;
            break;
        }
    }
}

void RibbonPosnEffectStateMachineUnlockExit(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineUnlockExit" << std::endl;
    resetLeFrntTurnLampRibbonUnlockAnimation();
    resetLeFrntTurnLampRibbonLockAnimation();
}

void RibbonPosnEffectStateMachineLockEntry(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineLockEntry" << std::endl;
}

void RibbonPosnEffectStateMachineLockExcute(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineLockExcute" << std::endl;
    switch(g_RibbonAnimationModel.posnMode_)
    {
        case Init:
        {
            if(isLeFrntTurnLampRibbonLockAnimationPlaying())
            {
                playLeFrntTurnLampRibbonLockAnimation();
            }
            else
            {
                //Ignore
            }
            g_RibbonView.model_->frntRibbonLampEffectShowSt_ = RibbonEffectShow_OFF;
            g_RibbonView.model_->frntRibbonLampEffectSt_     = RibbonEffectSel_Initial;
            break;
        }
        case Pause:
        {
            // std::cout << "Posn ignore pause" << std::endl;
            g_RibbonView.model_->frntRibbonLampEffectShowSt_ = RibbonEffectShow_Pause;
            break;
        }
        case Repeat:
        {
            playLeFrntTurnLampRibbonLockAnimation();
            repeatLeFrntTurnLampRibbonLockAnimation();
            break;
        }
        case Hold:
        {
            playLeFrntTurnLampRibbonLockAnimation();
            break;
        }
        case LeTurnLampOccupy:
        {
            if(g_RibbonAnimationModel.posnMode_ != g_RibbonAnimationModel.lastPosnMode_)
            {
                // std::cout << "LeTurnLampOccupy" << std::endl;
                justCloseRibbonLeFrntTurnLamp();
            }
            g_RibbonView.model_->frntRibbonLampEffectShowSt_ = RibbonEffectShow_Running;
            break;
        }
        default:
        {
                break;
        }
    }
}

void RibbonPosnEffectStateMachineLockExit(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineLockExit" << std::endl;
    resetLeFrntTurnLampRibbonUnlockAnimation();
    resetLeFrntTurnLampRibbonLockAnimation();
}

void RibbonPosnEffectStateMachineAllEntry(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineAllEntry" << std::endl;
}

void RibbonPosnEffectStateMachineAllExcute(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineAllExcute" << std::endl;
}

void RibbonPosnEffectStateMachineAllExit(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineAllExit" << std::endl;
    resetLeFrntTurnLampRibbonUnlockAnimation();
    resetLeFrntTurnLampRibbonLockAnimation();
}

void RibbonPosnEffectStateMachineOffEntry(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineOffEntry" << std::endl;
}

void RibbonPosnEffectStateMachineOffExcute(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineOffExcute" << std::endl;
}

void RibbonPosnEffectStateMachineOffExit(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineOffExit" << std::endl;
}

void RibbonPosnEffectStateMachineDefaultEntry(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineDefaultEntry" << std::endl;
}

void RibbonPosnEffectStateMachineDefaultExcute(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineDefaultExcute" << std::endl;
}

void RibbonPosnEffectStateMachineDefaultExit(void)
{
    // std::cout << "Base::Ctrl::RibbonPosnEffectStateMachineDefaultExit" << std::endl;
}


void RibbonPosnCtrlStateMachineOnEntry(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineOnEntry" << std::endl;
    resetLeFrntTurnLampRibbonUnlockAnimation();
}

static void RibbonPosnEffectShowExitWithState(RibbonPosnCtrlStateMachine_On* normalStateMachine, RibbonPosnEffectShowState inputState)
{
    switch(inputState)
    {
        case RibbonPosnEffectShowState_Default:
        {
            normalStateMachine->ribbonPosnEffectStateMachineDefault_.sm_.Exit();
            break;
        }

        case RibbonPosnEffectShowState_Unlock:
        {
            normalStateMachine->ribbonPosnEffectStateMachineUnlock_.sm_.Exit();
            break;
        }

        case RibbonPosnEffectShowState_Lock:
        {
            normalStateMachine->ribbonPosnEffectStateMachineLock_.sm_.Exit();
            break;
        }

        case RibbonPosnEffectShowState_Off:
        {
            normalStateMachine->ribbonPosnEffectStateMachineOff_.sm_.Exit();
            break;
        }

        case RibbonPosnEffectShowState_All:
        {
            normalStateMachine->ribbonPosnEffectStateMachineAll_.sm_.Exit();
            break;
        }

        default:
        {
            break;
        }
    }
}

static void RibbonPosnEffectShowExcuteWithState(RibbonPosnCtrlStateMachine_On* normalStateMachine, RibbonPosnEffectShowState inputState)
{
    switch(inputState)
    {
        case RibbonPosnEffectShowState_Default:
        {
            normalStateMachine->ribbonPosnEffectStateMachineDefault_.sm_.Excute();
            break;
        }

        case RibbonPosnEffectShowState_Unlock:
        {
            normalStateMachine->ribbonPosnEffectStateMachineUnlock_.sm_.Excute();
            break;
        }

        case RibbonPosnEffectShowState_Lock:
        {
            normalStateMachine->ribbonPosnEffectStateMachineLock_.sm_.Excute();
            break;
        }

        case RibbonPosnEffectShowState_Off:
        {
            normalStateMachine->ribbonPosnEffectStateMachineOff_.sm_.Excute();
            break;
        }

        case RibbonPosnEffectShowState_All:
        {
            normalStateMachine->ribbonPosnEffectStateMachineAll_.sm_.Excute();
            break;
        }

        default:
        {
            break;
        }
    }
}

static void RibbonPosnEffectShowEntryWithState(RibbonPosnCtrlStateMachine_On* normalStateMachine, RibbonPosnEffectShowState inputState)
{
    switch(inputState)
    {
        case RibbonPosnEffectShowState_Default:
        {
            normalStateMachine->ribbonPosnEffectStateMachineDefault_.sm_.Entry();
            break;
        }

        case RibbonPosnEffectShowState_Unlock:
        {
            normalStateMachine->ribbonPosnEffectStateMachineUnlock_.sm_.Entry();
            break;
        }

        case RibbonPosnEffectShowState_Lock:
        {
            normalStateMachine->ribbonPosnEffectStateMachineLock_.sm_.Entry();
            break;
        }

        case RibbonPosnEffectShowState_Off:
        {
            normalStateMachine->ribbonPosnEffectStateMachineOff_.sm_.Entry();
            break;
        }

        case RibbonPosnEffectShowState_All:
        {
            normalStateMachine->ribbonPosnEffectStateMachineAll_.sm_.Entry();
            break;
        }

        default:
        {
            break;
        }
    }
}

void RibbonPosnCtrlStateMachineOnExcute(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineOnExcute" << std::endl;
    if(g_TurnLastState.ribbonPosnEffectShowState_ != g_TurnNewState.ribbonPosnEffectShowState_)
    {
        RibbonPosnEffectShowExitWithState(&g_RibbonPosnCtrlStateMachineOn, g_TurnLastState.ribbonPosnEffectShowState_);
        RibbonPosnEffectShowEntryWithState(&g_RibbonPosnCtrlStateMachineOn, g_TurnNewState.ribbonPosnEffectShowState_);
    }
    RibbonPosnEffectShowExcuteWithState(&g_RibbonPosnCtrlStateMachineOn, g_TurnNewState.ribbonPosnEffectShowState_);

    UpdateRibbonPosnEffectShowState(g_TurnNewState.ribbonPosnEffectShowState_, &g_TurnLastState.ribbonPosnEffectShowState_);
}

void RibbonPosnCtrlStateMachineOnExit(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineOnExit" << std::endl;
    RibbonPosnEffectShowExitWithState(&g_RibbonPosnCtrlStateMachineOn, g_TurnNewState.ribbonPosnEffectShowState_);

    UpdateRibbonPosnEffectShowState(RibbonPosnEffectShowState_Invaild, &g_TurnLastState.ribbonPosnEffectShowState_);
}

void RibbonPosnCtrlStateMachineAgainEntry(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineAgainEntry" << std::endl;
    resetLeFrntTurnLampRibbonUnlockAnimation();
    resetLeFrntTurnLampRibbonLockAnimation();
}

void RibbonPosnCtrlStateMachineAgainExcute(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineAgainExcute" << std::endl;
}

void RibbonPosnCtrlStateMachineAgainExit(void)
{
    // std::cout << "Base::RibbonPosnCtrlStateMachineAgainExit" << std::endl;
}

